<?php

namespace App\Service\OpenShop\Import\OpenFull;

use App\Enums\OpenShop\InvestmentPromotion\SignOrderEnum;
use App\Enums\OpenShop\InvestmentPromotion\SiteLocationEnum;
use App\Enums\OpenShop\MissionTemplateEnum;
use App\Exceptions\Custom\CustomHttpResponseException;
use App\Library\FeiShu\SendFs;
use App\Library\Rms\RmsShopApi;
use App\Library\Rms\RmsUserApi;
use App\Models\OpenShop\InvestmentPromotion\OpenShopContractTemplateModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopLocationModel;
use App\Models\OpenShop\InvestmentPromotion\OpenShopSignOrderModel;
use App\Models\OpenShop\StartBusiness\OpenShopStartBusinessModel;
use App\Remote\Rms\RmsShopRemote;
use App\Service\OpenShop\Feishu\OrganizationManageService;
use App\Service\OpenShop\User\RmsUserService;
use PHPUnit\Util\Exception;

class OpenFullParam
{
    public int     $shopCode = 0;
    private ?string $shopName;
    public bool    $newShop;

//    public string $name;
//    public ?string $identityNo;
//    public string $phone;

    // 门店状态
    public ?string $shopStatusText;
    public int     $shopStatus; // 0正常 1停用

    // 门店选址范围
    public string $siteMerge;
    public int    $siteProvinceCode = 0;
    public int    $siteCityCode     = 0;
    public int    $siteDistrictCode = 0;
    public string $siteAddress = '';

    public ?string $excelProvinceName;
    public ?string $excelCityName;
    public ?string $excelDistrictName;

    // 经营类型：直营店、加盟店、加盟转直营、直营转加盟
    public string $shopTypeText;

    // 铺位类型：街边店、商场店、特殊店
    public ?string $shopLocationTypeText;
    public int $shopLocationType;

    // 收银系统：夸父收银、美团、第三方
    public ?string $cashierTypeText;
    public int     $cashType;

    private ?int $contractStartDate; // 合同开始时间
    public int   $contractStartTime; // 合同开始时间
    private ?int $contractEndDate; // 合同结束时间
    public int   $contractEndTime;
    private ?int $confirmLocationDate; // 确址日期
    public int   $confirmLocationTime;
    private ?int $preparationCompleteDate; // 筹备完成日期
    public int   $preparationCompleteTime;

    private ?int $startBusinessDate; // 预计开业时间
    public int   $startBusinessTime; // 预计开业时间

    public ?float $area; // 面积

    public ?float $rent; // 房租

    public ?float $salary; // 人工

    public ?float $energy; // 能源

    // 选址分类：推荐选址、自带址、自带址-现场、自带址-远程
    public ?string $messageFromText;
    public int $messageFrom;

    // 顾问
    public ?string $managerSalesName; // 招商顾问
    public ?array  $managerSales;

    public ?string $managerDevelopName; // 开发顾问
    public ?array  $managerDevelop;

    public ?string $managerDesignName = ''; // 设计顾问
    public ?array  $managerDesign;

    public ?string $managerPrepareName; // 筹备顾问
    public ?array  $managerPrepare;

    public ?string $managerOperateName; // 营运负责人，督导
    public ?array  $managerOperate;

    public ?string $managerProvinceName; // 省总
    public ?array  $managerProvince; // 省总

    public ?string $friendlyText; // 配合程度
    public int $friendly;


    // 加盟政策模板
    public int    $contractTemplateId;
    public string $contractTemplateText = '泛微历史导入模板';

    public array $shopTag = ['开业门店导入20220711']; // 门店标签

    public array $rmsShop = [];

    // 过滤不处理的shopCode
    public array $filterShopCodes = [
        2387,
        2386,
        2455,
        2462,
        2480,
        802,
        2351,
        2380,
        580,
        1328,
        1739,
        28,
    ];


    public int     $row;
    private string $errMsg    = '';
    private string $noticeMsg = '';

    // 流程中创建的属性
    public string $orderNo;

    private bool $debug = true;

    // 要手动insert的
    // 1256
    // 0293
    // 0028

    public function init(array $data, int $row, array $rmsShop)
    {
        $this->row     = $row;
        $this->rmsShop = $rmsShop;

        if ($row == 1) {

            // 检查列名
            $this->checkColumn($data);
            return $this;
        }

        dump($data);

        list(
            $this->shopCode,
            $this->shopName,
            $_,
            $this->shopStatusText,
            $this->excelProvinceName,
            $this->excelCityName,
            $this->excelDistrictName,
            $this->shopTypeText,
            $this->shopLocationTypeText,
            $this->cashierTypeText,
            $this->contractStartDate,
            $this->contractEndDate,
            $this->confirmLocationDate,
            $this->preparationCompleteDate,
            $this->startBusinessDate,
            $_,
            $_,
            $area,
            $rent,
            $this->salary,
            $this->energy,
            $this->messageFromText,
            $this->managerSalesName,
            $this->managerDevelopName,
            $this->managerPrepareName,
            $this->managerOperateName,
            $this->friendlyText,
            ) = $data;

        if (is_numeric($rent)) {
            $this->rent = $rent;
        } else {
            $this->rent = 0;
        }

        if (is_numeric($area)) {
            $this->area = $area;
        } else {
            $this->area = 0;
        }

        dump("shopCode: {$this->shopCode}");

        return $this;
    }

    /**
     * 检查列名
     * @param array $data
     * @return void
     */
    private function checkColumn(array $data): void
    {
        $formColumn = [
            '铺位号',
            '门店名称',
            '店铺地址',
            '状态',
            '省份',
            '城市',
            '区县',
            '经营类型',
            '铺位类型',
            '收银系统',
            '合同开始日期',
            '合同结束日期',
            '确址日期',
            '筹备完成日期',
            '开业日期',
            '闭店时间',
            '外卖介入时间',
            '面积',
            '房租',
            '人工',
            '能源',
            '选址分类',
            '加盟顾问',
            '开发顾问',
            '筹备顾问',
            '营运顾问',
            '配合程度',
        ];

        foreach ($formColumn as $k => $v) {
            $dataV = $data[$k] ?? '';

            if (strpos($dataV, $v) === false) {
                $this->errMsg .= sprintf("第%d列，列名错误。应为：%s，传入：%s", $k + 1, $v, $dataV) . PHP_EOL;
            }
        }

        if ($this->errMsg) {
            SendFs::newRobot(SendFs::ROBOT_INTERNAL)->setTitleContent("导入历史全量开店订单模板异常", $this->errMsg)->send();
            dump($this->errMsg);
            die;
        }
    }

    public function prepareParam(): self
    {
        // 列名不校验
        if ($this->row == 1) {
            return $this;
        }

        try {
            $this->checkStatus();
            $this->checkShopType();
            $this->checkRmsShop();
            $this->checkShopCode();
            $this->checkContractTemplateText();
            $this->checkCashierType();
            $this->checkSiteMerge();
            $this->checkDate();
            $this->checkManager();
            $this->checkFriendly();
            $this->checkMessageFrom();
            $this->checkShopLocationType();

        } catch (CustomHttpResponseException $e) {
            $this->errMsg .= "第{$this->row}行，门店编号：{$this->shopCode} " . ($e->getResponse()->original['msg'] ?? '') . PHP_EOL;
        } catch (\Exception $e) {
            $this->errMsg .= "第{$this->row}行，门店编号：{$this->shopCode} " . $e->getMessage() . PHP_EOL;
        }

        return $this;
    }

    public function getErrMsg(): string
    {
        return $this->errMsg;
    }

    public function getNoticeMsg(): string
    {
        return $this->noticeMsg;
    }

    private function dumpFunctionName(string $functionName)
    {
        if ($this->debug) {
            dump($functionName);
        }
    }

    private function checkShopLocationType()
    {
        if ($this->shopLocationTypeText == '街边店') {
            $this->shopLocationType = SiteLocationEnum::SITE_TYPE_6;
        } elseif ($this->shopLocationTypeText == '商场店') {
            $this->shopLocationType = SiteLocationEnum::SITE_TYPE_18;
        } else {
            $this->shopLocationType = SiteLocationEnum::SITE_TYPE_18;
        }
    }

    private function checkStatus()
    {
        if ($this->shopStatusText == '正常营业' || $this->shopStatusText == '暂停营业' || $this->shopStatusText == '迁址中') {
            $this->shopStatus = RmsShopApi::SHOP_STATUS_NORMAL;
        } elseif ($this->shopStatusText == '闭店') {
            $this->shopStatus = RmsShopApi::SHOP_STATUS_BAN;
        } else {
            throw new \Exception('不存在的shopStatusText:'.$this->shopStatusText);
        }

        $this->dumpFunctionName(__FUNCTION__);
    }

    private function checkShopType()
    {
        switch ($this->shopTypeText) {
            case '加盟店':
                $this->shopType = RmsShopApi::SHOP_TYPE_LEAGUE;
                break;
            case '直营店':
                $this->shopType = RmsShopApi::SHOP_TYPE_DIRECT;
                break;
            case '加盟转直营':
                $this->shopTag[] = $this->shopTypeText;
                $this->shopType  = RmsShopApi::SHOP_TYPE_DIRECT;
                break;
            case '直营转加盟':
                $this->shopTag[] = $this->shopTypeText;
                $this->shopType  = RmsShopApi::SHOP_TYPE_LEAGUE;
                break;
            default:
                throw new \Exception('错误的经营类型');
        }
    }

    private function checkRmsShop()
    {
        if (in_array($this->excelProvinceName, ['澳大利亚省', '法国省', '美国省', '日本省'])) {
            throw new \Exception('外国门店不做导入');
        }

        if (in_array($this->shopCode, $this->filterShopCodes)) {
            throw new \Exception("省区推送门店，不作处理");
        }

        if ($this->rmsShop) {
            return;
        }

        if ($this->shopStatus == RmsShopApi::SHOP_STATUS_NORMAL) {
            throw new Exception("正常营业shopCode:{$this->shopCode} rms未建店");
        }

        if ($this->shopStatus == RmsShopApi::SHOP_STATUS_BAN) {

            $siteData = (new RmsShopApi())->getAreaCodeByArea([
                $this->excelProvinceName,
                $this->excelCityName,
                $this->excelDistrictName
            ])['data'];


            $adCityCode   = $siteData[1]['code'] ?? 0;
            $adRegionCode = $siteData[2]['code'] ?? 0;
            if (!$adCityCode) {
                throw new \Exception("找不到城市:{$this->excelCityName}");
            }

            $response = (new RmsShopApi())->createShop($this->shopName, '19999999999', '默认姓名', $this->shopCode, $this->shopType, $this->shopStatus, $adCityCode, $adRegionCode, (string)$this->excelDistrictName);

            if (!isset($response['code']) || !$response['code']) {
                throw new Exception("建店失败：" . ($response['msg'] ?? ''));
            }

            $this->rmsShop = RmsShopRemote::getShopFieldsByCodes([$this->shopCode], ['id', 'shopCode', 'name', 'shopMobile', 'address', 'addressPrefix', 'province', 'city', 'district'])['shopList'][0] ?? [];
        }

        $this->dumpFunctionName(__FUNCTION__);
    }

    private function checkCashierType()
    {
        switch ($this->cashierTypeText) {
            case '夸父收银':
                $this->cashType = SiteLocationEnum::CASE_REGISTER_TYPE_1;
                break;
            case '第三方':
                $this->cashType = SiteLocationEnum::CASE_REGISTER_TYPE_2;
                break;
            case '美团':
                $this->cashType = SiteLocationEnum::CASE_REGISTER_TYPE_3;
                break;
//            case '哗啦啦':
//                $this->cashType = SiteLocationEnum::CASE_REGISTER_TYPE_4;
//                break;
            default:
                $this->cashType = SiteLocationEnum::CASE_REGISTER_TYPE_2;
                break;
        }

        $this->dumpFunctionName(__FUNCTION__);
    }


    private function checkShopCode(): void
    {
        if (!$this->shopCode) {
            throw new \Exception("shopCode不能为空");
        }

        if (in_array($this->shopCode, $this->filterShopCodes)) {
            throw new \Exception("省区推送门店，不作处理");
        }

        // openShop有没有
        $signOrder = OpenShopSignOrderModel::query()
                                           ->where('shopCode', $this->shopCode)
                                           ->where('status', '!=', SignOrderEnum::ORDER_STATUS_NO)
                                           ->first();
        if (!$signOrder) {
            $this->newShop = true;

            $this->dumpFunctionName(__FUNCTION__);
            return;
        }

        $this->newShop = false;


        if ($signOrder->status != SignOrderEnum::ORDER_STATUS_COMPLETE) {
            throw new \Exception("openShop店铺未完成开业。excel状态：{$this->shopStatusText} 开店状态：".MissionTemplateEnum::STEP_STATUS_TEXT[$signOrder->progressRel->nowStepStatus]);
        }

        $this->dumpFunctionName(__FUNCTION__);
    }


    private function checkSiteMerge(): void
    {
        $this->siteMerge        = str_replace('-', '/', $this->rmsShop['addressPrefix'] ?? '');
        $this->siteProvinceCode = $this->rmsShop['province'];
        $this->siteCityCode     = $this->rmsShop['city'];
        $this->siteDistrictCode = $this->rmsShop['district'];
        $this->siteAddress      = $this->rmsShop['address'];

        if (!$this->siteProvinceCode) {
            throw new \Exception('门店省份provinceCode未配置');
        }

        $this->dumpFunctionName(__FUNCTION__);
    }

    private function checkContractTemplateText(): void
    {
        $template = OpenShopContractTemplateModel::query()->where('templateName', $this->contractTemplateText)->first();
        if (!$template) {
            throw new \Exception("不存在的加盟政策");
        }

        $this->contractTemplateId = $template->id;

        $this->dumpFunctionName(__FUNCTION__);
    }

    private function checkDate(): void
    {
        $this->contractStartTime       = $this->convertExcelDate($this->contractStartDate);
        $this->contractEndTime         = $this->convertExcelDate($this->contractEndDate);
        $this->startBusinessTime       = $this->convertExcelDate($this->startBusinessDate);
        $this->confirmLocationTime     = $this->convertExcelDate($this->confirmLocationDate);
        $this->preparationCompleteTime = $this->convertExcelDate($this->preparationCompleteDate);

        $this->dumpFunctionName(__FUNCTION__);
    }

    private function convertExcelDate(?int $excelDate): int
    {
        $excelInitDate = 25569; // 1970的值

        if ($excelDate) {
            $excelTime = strtotime(date('Ymd', ($excelDate - $excelInitDate) * 86400 + 8 * 3600));
        } else {
            $excelTime = 0;
        }

        return (int)$excelTime;
    }

    private function checkManager(): void
    {
        // 根据开店组织，获取省总
        $manager = OrganizationManageService::getOrganizationInfoByProvinceCodeCode($this->siteProvinceCode);
        if (!$manager) {
            throw new \Exception($this->siteMerge . ";获取开店组织失败;provinceCode:{$this->siteProvinceCode}");
        }

        $managerLists = collect(RmsUserService::getRmsUserInfoByUserIds([$manager['operationUid']], [],
                true)['data'] ?? [])
            ->keyBy('id');

        $this->managerProvinceName = $managerLists[$manager['operationUid']]['username'] ?? '';
        $this->managerProvince     = $managerLists[$manager['operationUid']] ?? [];
        if (!$this->managerProvinceName) {
            throw new \Exception($this->siteMerge . ";获取营运顾问失败;provinceCode:{$this->siteProvinceCode} userId:{$manager['operationUid']}");
        }

        // 招商
        if (!$this->managerSalesName) {
            $this->managerSalesName = '石尧（山治）';
        }
        $this->managerSales = (new RmsUserApi())->getInfoByUsernames([$this->managerSalesName], true)['data'][0] ?? [];
        if (!$this->managerSales) {
            throw new \Exception("rms不存在顾问：{$this->managerSalesName}");
        }

        // 开发
        if (!$this->managerDevelopName) {
            $this->managerDevelopName = '石尧（山治）';
        }
        $this->managerDevelop = (new RmsUserApi())->getInfoByUsernames([$this->managerDevelopName],
                true)['data'][0] ?? [];
        if (!$this->managerDevelop) {
            throw new \Exception("rms不存在顾问：{$this->managerDevelopName}");
        }

        // 设计
        if (!$this->managerDesignName) {
            $this->managerDesignName = '石尧（山治）';
        }
        $this->managerDesign = (new RmsUserApi())->getInfoByUsernames([$this->managerDesignName],
                true)['data'][0] ?? [];
        if (!$this->managerDesign) {
            throw new \Exception("rms不存在顾问：{$this->managerDesignName}");
        }

        // 营运
        if (!$this->managerOperateName) {
            $this->managerOperateName = '石尧（山治）';
        }
        $this->managerOperate = (new RmsUserApi())->getInfoByUsernames([$this->managerOperateName],
                true)['data'][0] ?? [];
        if (!$this->managerOperate) {
            throw new \Exception("rms不存在顾问：{$this->managerOperateName}");
        }

        // 筹备
        if (!$this->managerPrepareName) {
            $this->managerPrepareName = '石尧（山治）';
        }
        $this->managerPrepare = (new RmsUserApi())->getInfoByUsernames([$this->managerPrepareName],
                true)['data'][0] ?? [];
        if (!$this->managerPrepare) {
            throw new \Exception("rms不存在顾问：{$this->managerOperateName}");
        }

        $this->dumpFunctionName(__FUNCTION__);
    }

    private function checkFriendly(): void
    {
        if ($this->friendlyText == '高') {
            $this->friendly = OpenShopStartBusinessModel::DEGREE_COOPERATION_TYPE_1;
        } elseif ($this->friendlyText == '中') {
            $this->friendly = OpenShopStartBusinessModel::DEGREE_COOPERATION_TYPE_2;
        } else {
            $this->friendly = OpenShopStartBusinessModel::DEGREE_COOPERATION_TYPE_3;
        }

        $this->dumpFunctionName(__FUNCTION__);
    }

    private function checkMessageFrom(): void
    {
        switch ($this->messageFromText ) {
            case '推荐选址':
                $this->messageFrom = SiteLocationEnum::MESSAGE_FROM_TYPE_2;
                break;
            case '自带址':
                $this->messageFrom = SiteLocationEnum::MESSAGE_FROM_TYPE_1;
                break;
            case '自带址-现场':
                $this->messageFrom = SiteLocationEnum::MESSAGE_FROM_TYPE_1;
                break;
            case '自带址-远程':
                $this->messageFrom = SiteLocationEnum::MESSAGE_FROM_TYPE_3;
                break;
            default:
                $this->messageFrom = SiteLocationEnum::MESSAGE_FROM_TYPE_2;
                break;
        }

        $this->dumpFunctionName(__FUNCTION__);
    }
}
